/*
 * SPDX-FileCopyrightText: 2024 Andrew Gunnerson
 * SPDX-License-Identifier: GPL-3.0-only
 */

package com.sanji.audio_test.rule

import android.app.Activity
import android.content.Intent
import android.os.Bundle
import androidx.fragment.app.viewModels
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import androidx.preference.Preference
import androidx.preference.get
import androidx.preference.size
import com.sanji.audio_test.ContactGroupInfo
import com.sanji.audio_test.PreferenceBaseFragment
import com.sanji.audio_test.R
import com.google.android.material.snackbar.Snackbar
import kotlinx.coroutines.launch

/**
 * 选择联系人组Fragment
 * 用于显示和选择联系人组的界面片段
 */
class PickContactGroupFragment : PreferenceBaseFragment(), Preference.OnPreferenceClickListener {
    // 通过委托获取ViewModel实例
    private val viewModel: PickContactGroupViewModel by viewModels()

    /**
     * 创建偏好设置界面
     * @param savedInstanceState 保存的实例状态
     * @param rootKey 根键值
     */
    override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
        // 从资源文件加载偏好设置
        setPreferencesFromResource(R.xml.record_rules_preferences, rootKey)

        // 启动协程监听提醒事件
        lifecycleScope.launch {
            repeatOnLifecycle(Lifecycle.State.STARTED) {
                viewModel.alerts.collect {
                    it.firstOrNull()?.let { alert ->
                        onAlert(alert)
                    }
                }
            }
        }

        // 启动协程监听联系人组数据变化
        lifecycleScope.launch {
            repeatOnLifecycle(Lifecycle.State.STARTED) {
                viewModel.groups.collect {
                    updateGroups(it)
                }
            }
        }
    }

    /**
     * 更新联系人组显示
     * 清除现有偏好设置项并添加新的联系人组项
     * @param newGroups 新的联系人组列表
     */
    private fun updateGroups(newGroups: List<ContactGroupInfo>) {
        val context = requireContext()

        // 清除所有现有偏好设置项
        for (i in (0 until preferenceScreen.size).reversed()) {
            val p = preferenceScreen[i]
            preferenceScreen.removePreference(p)
        }

        // 为每个联系人组创建偏好设置项
        for ((i, group) in newGroups.withIndex()) {
            val p = Preference(context).apply {
                key = PREF_GROUP_PREFIX + i
                isPersistent = false
                title = group.title
                summary = group.accountName ?: "Local group"
                isIconSpaceReserved = false
                onPreferenceClickListener = this@PickContactGroupFragment
            }
            preferenceScreen.addPreference(p)
        }
    }

    /**
     * 偏好设置项点击事件处理
     * @param preference 被点击的偏好设置项
     * @return 是否处理了点击事件
     */
    override fun onPreferenceClick(preference: Preference): Boolean {
        when {
            // 处理联系人组项点击
            preference.key.startsWith(PREF_GROUP_PREFIX) -> {
                val index = preference.key.substring(PREF_GROUP_PREFIX.length).toInt()
                val activity = requireActivity()

                // 设置返回结果并结束Activity
                activity.setResult(Activity.RESULT_OK, Intent().putExtra(
                    PickContactGroupActivity.RESULT_CONTACT_GROUP,
                    viewModel.groups.value[index],
                ))
                activity.finish()

                return true
            }
        }

        return false
    }

    /**
     * 处理提醒事件
     * @param alert 提醒事件
     */
    private fun onAlert(alert: PickContactGroupAlert) {
        val msg = when (alert) {
            is PickContactGroupAlert.QueryFailed ->
                "Failed to query contact groups: ${alert.error}"
        }

        // 显示Snackbar提醒
        Snackbar.make(requireView(), msg, Snackbar.LENGTH_LONG)
            .addCallback(object : Snackbar.Callback() {
                override fun onDismissed(transientBottomBar: Snackbar?, event: Int) {
                    viewModel.acknowledgeFirstAlert()
                }
            })
            .show()
    }

    // 伴生对象
    companion object {
        // 联系人组偏好设置项前缀
        private const val PREF_GROUP_PREFIX = "group_"
    }
}